home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 17
/
CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso
/
CUCD
/
Programming
/
DiceSource
/
src
/
das
/
subs.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-09
|
7KB
|
417 lines
/*
* (c)Copyright 1992-1997 Obvious Implementations Corp. Redistribution and
* use is allowed under the terms of the DICE-LICENSE FILE,
* DICE-LICENSE.TXT.
*/
/*
* SUBS.C
*
*/
#include "defs.h"
#include <stdarg.h>
#include <fcntl.h>
#ifndef O_BINARY
#define O_BINARY 0
#endif
Prototype char *EAToString(EffAddr *);
Prototype void syntax(long);
Prototype void RegMaskToStr(char *, long);
Prototype void cvtstrtolower(char *);
Prototype int OnlyOneRegister(long);
Prototype void cerror(short, ...);
Prototype long Align(long, long);
Prototype long AlignDelta(long, long);
Prototype char *MakeTmpLabelName(void);
Prototype char ExtWordToReg(uword);
Prototype char *ObtainErrorString(short);
Prototype void NoMemory(void);
Prototype void ExitError(short);
Prototype void eprintf(const char *ctl, ...);
Prototype void veprintf(const char *ctl, va_list va);
Prototype void eputc(char c);
Local char *DumpRegs(char *, short, char, char);
char *ErrorFileName = DCC "config/dice.errors";
char *ErrorAry;
long ErrorArySize;
char ErrBuf[128];
char *
EAToString(ea)
EffAddr *ea;
{
static char Buf[2][128];
static int Bi;
char *ptr;
char rc = (ea->Reg1 >= RB_AREG) ? 'A' : 'D';
Bi = !Bi;
ptr = Buf[Bi];
if (ea->Mode1 == 0)
return("-");
switch(ea->Mode1) {
case AB_DN:
case AB_AN:
*ptr++ = rc;
*ptr++ = (ea->Reg1 & 7) + '0';
*ptr = 0;
break;
case AB_MMIND:
*ptr++ = '-';
case AB_INDAN:
case AB_INDPP:
*ptr++ = '(';
*ptr++ = rc;
*ptr++ = (ea->Reg1 & 7) + '0';
*ptr++ = ')';
*ptr = 0;
if (ea->Mode1 != AB_INDPP)
break;
*ptr++ = '+';
*ptr = 0;
break;
case AB_IMM:
*ptr++ = '#';
*ptr = 0;
case AB_ABSW:
case AB_ABSL:
case AB_OFFAN:
case AB_OFFIDX:
case AB_OFFPC:
case AB_OFFIDXPC:
case AB_BBRANCH:
case AB_WBRANCH:
if (ea->Label1) {
strcpy(ptr, ea->Label1->Name);
ptr += strlen(ptr);
if (ea->Offset1)
strcpy(ptr, "+");
}
if (ea->Offset1) {
sprintf(ptr, "%ld", ea->Offset1);
ptr += strlen(ptr);
}
switch(ea->Mode1) {
case AB_OFFAN:
sprintf(ptr, "(A%d)", ea->Reg1 - RB_AREG);
break;
case AB_OFFIDX:
{
short reg2 = ExtWordToReg(ea->ExtWord);
char x2 = (reg2 >= RB_AREG) ? 'A' : 'D';
char s2 = (ea->ExtWord & EXTF_LWORD) ? 'L' : 'W';
sprintf(ptr, "(A%d,%c%d.%c)", ea->Reg1 - RB_AREG, x2, reg2 & 7, s2);
}
break;
case AB_OFFPC:
strcpy(ptr, "(PC)");
break;
case AB_OFFIDXPC:
{
short reg2 = ExtWordToReg(ea->ExtWord);
char x2 = (reg2 >= RB_AREG) ? 'A' : 'D';
char s2 = (ea->ExtWord & EXTF_LWORD) ? 'L' : 'W';
sprintf(ptr, "(PC,%c%d.%c)", x2, reg2 & 7, s2);
}
break;
}
break;
case AB_REGS:
RegMaskToStr(ptr, ea->ExtWord);
break;
case AB_CCR:
strcpy(ptr, "CCR");
break;
case AB_SR:
strcpy(ptr, "SR");
break;
case AB_USP:
strcpy(ptr, "USP");
break;
default:
sprintf(ptr, "?%d", ea->Mode1);
break;
}
return(Buf[Bi]);
}
void
syntax(long n)
{
cerror(EERROR_SYNTAX);
}
char *
DumpRegs(char *ptr, short rbefore, char rs, char re)
{
char ac = (rs >= RB_AREG) ? 'A' : 'D';
if (rbefore)
*ptr++ = '/';
if (rs < 0)
return(ptr);
if (rs == re) {
*ptr++ = ac;
*ptr++ = '0' + (rs & 7);
return(ptr);
}
*ptr++ = ac;
*ptr++ = '0' + (rs & 7);
*ptr++ = '-';
*ptr++ = ac;
*ptr++ = '0' + (re & 7);
return(ptr);
}
void
RegMaskToStr(ptr, mask)
char *ptr;
long mask;
{
char *base = ptr;
short regno = -1;
short lastreg = -1;
short i;
printf("mask %04lx\n", mask);
for (i = 0; i < 16; ++i) {
if (i == 8) {
ptr = DumpRegs(ptr, ptr != base, regno, lastreg);
regno = lastreg = -1;
}
if (mask & (1 << i)) {
if (regno < 0) {
regno = lastreg = i;
} else {
if (lastreg == i - 1) {
lastreg = i;
} else {
ptr = DumpRegs(ptr, ptr != base, regno, lastreg);
regno = lastreg = i;
}
}
}
}
ptr = DumpRegs(ptr, ptr != base, regno, lastreg);
*ptr = 0;
}
void
cvtstrtolower(str)
char *str;
{
while (*str) {
if (*str >= 'A' && *str <= 'Z')
*str |= 0x20;
++str;
}
}
/*
* Returns the regno specified in the mask or -1 if more than one register
* or no registers are specified.
*/
int
OnlyOneRegister(long mask)
{
short i;
for (i = 0; i < 16; ++i) {
if (mask & (1 << i)) {
mask &= ~(1 << i);
if (mask == 0)
return((int)i);
break;
}
}
return(-1);
}
void
cerror(short errorId, ...)
{
static const char *MsgBase[] = {
"Error", "SoftError", "Warning", "Note", "Fatal", "FatalSoftError"
};
va_list va;
if ((errorId & EF_MASK) != EF_VERBOSE) {
char *nm;
long line;
nm = AsmFileName;
line = LineNo;
if (DebugLineNo && (SrcFileName != NULL))
{
nm = SrcFileName;
line = DebugLineNo;
}
eprintf("DAS: \"%s\" L:%d %.*s%.*s:%d ", nm, line,
((ErrorOpt == 2) ? 4 : 0), "C:0 ",
((ErrorOpt == 2) ? 1 : (int)strlen(MsgBase[errorId >> 12])),
MsgBase[errorId >> 12],
errorId & 0x0FFF
);
}
va_start(va, errorId);
veprintf(ObtainErrorString(errorId & 0x0FFF), va);
va_end(va);
eputc('\n');
if ((errorId >> 12) >= __FATALPT__) {
ExitError(20);
}
switch(errorId & EF_MASK) {
case EF_WARN:
case EF_SOFTWARN:
if (ExitCode < 5)
ExitCode = 5;
break;
case EF_ERROR:
if (ExitCode < 20)
ExitCode = 20;
break;
}
}
void
ExitError(short code)
{
if (Fo)
fclose(Fo);
if (FoName)
remove(FoName);
if (ExitCode < code)
ExitCode = code;
exit(ExitCode);
}
long
Align(offset, align)
long offset;
long align;
{
long n;
n = offset & (align - 1);
if (n)
n = align - n;
return(offset + n);
}
long
AlignDelta(offset, align)
long offset;
long align;
{
long n = offset & (align - 1);
if (n)
n = align - n;
return(n);
}
char *
MakeTmpLabelName()
{
static long id;
char *buf = malloc(16);
if (buf == NULL)
NoMemory();
sprintf(buf, "&$%ld", id++);
return(buf);
}
void
NoMemory()
{
eprintf("NO MEMORY!\n");
ExitError(25);
}
void
eprintf(const char *ctl, ...)
{
va_list va;
va_start(va, ctl);
veprintf(ctl, va);
va_end(va);
}
void
veprintf(const char *ctl, va_list va)
{
vfprintf(stderr, ctl, va);
if (ErrorFi)
vfprintf(ErrorFi, ctl, va);
}
void
eputc(char c)
{
fputc(c, stderr);
if (ErrorFi)
fputc(c, ErrorFi);
}
char
ExtWordToReg(uword extword)
{
if (extword & EXTF_AREG)
return(((extword >> 12) & 7) + RB_AREG);
return((extword >> 12) & 7);
}
char *
ObtainErrorString(short errNum)
{
short i;
if (ErrorAry == NULL) {
int fd;
short siz;
if ((fd = open(ErrorFileName, O_RDONLY|O_BINARY)) < 0) {
sprintf(ErrBuf, "(can't open %s!)", ErrorFileName);
return(ErrBuf);
}
siz = lseek(fd, 0L, 2);
lseek(fd, 0L, 0);
ErrorAry = malloc(siz + 1);
read(fd, ErrorAry, siz);
close(fd);
{
char *ptr;
for (ptr = strchr(ErrorAry, '\n'); ptr; ptr = strchr(ptr + 1, '\n'))
*ptr = 0;
}
ErrorAry[siz] = 0;
ErrorArySize = siz;
}
for (i = 0; i < ErrorArySize; i += strlen(ErrorAry + i) + 1) {
char *ptr;
if (ErrorAry[i] == 'A' && ErrorAry[i+1] == 'S' && strtol(ErrorAry + i + 3, &ptr, 10) == errNum)
return(ptr + 1);
}
sprintf(ErrBuf, "(no entry in %s for error)", ErrorFileName);
return(ErrBuf);
}